struct VS_INPUT
{
	float3	Position		: POSITION;
	float3	Normal			: NORMAL;
	
#ifdef DEF_ENABLE_TEXCOORD0
	float2	TEX_TEXCOORD0	: TEXCOORD0;
#endif
#ifdef DEF_ENABLE_TEXCOORD1
	float2	TEX_TEXCOORD1	: TEXCOORD1;
#endif
#ifdef DEF_ENABLE_TEXCOORD2
	float2	TEX_TEXCOORD2	: TEXCOORD2;
#endif
#ifdef DEF_ENABLE_TEXCOORD3
	float2	TEX_TEXCOORD3	: TEXCOORD3;
#endif
};

struct VS_OUTPUT
{
	float4 	Position		: SV_POSITION;
	float3	Normal			: TEXCOORD4;
#ifdef DEF_ENABLE_TEXCOORD0
	float2	TEX_TEXCOORD0	: TEXCOORD0;
#endif
#ifdef DEF_ENABLE_TEXCOORD1
	float2	TEX_TEXCOORD1	: TEXCOORD1;
#endif
#ifdef DEF_ENABLE_TEXCOORD2
	float2	TEX_TEXCOORD2	: TEXCOORD2;
#endif
#ifdef DEF_ENABLE_TEXCOORD3
	float2	TEX_TEXCOORD3	: TEXCOORD3;
#endif
};

struct PS_OUTPUT
{
	float4 Colour			: SV_Target;
};

cbuffer Constants
{
	matrix	g_objectToWorld;
	matrix	g_worldToScreen;
	
	// Material properties
#ifdef DEF_DIFFUSE_FIXED
	float4	g_DiffuseColour;
#endif

#ifdef DEF_DIFFUSE_TEXTURE
	Texture2D g_DiffuseTexture;
	SamplerState g_DiffuseTextureSampler;
#endif

#ifdef DEF_AMBIENT_FIXED
	float4	g_AmbientColour;
#endif

#ifdef DEF_AMBIENT_TEXTURE
	Texture2D g_AmbientTexture;
	SamplerState g_AmbientTextureSampler;
#endif
	
	// Lighting properties
	float4	g_Light_Direction;
	float4	g_Light_AmbientColour;
	float4	g_Light_DiffuseColour;
};

VS_OUTPUT vs_main(VS_INPUT input)
{
	VS_OUTPUT output = (VS_OUTPUT)0;
	float3x3 objectToWorldRotation = (float3x3)g_objectToWorld;
	float4x4 objectToScreen = mul(g_worldToScreen,g_objectToWorld);
	output.Position = mul(objectToScreen, float4(input.Position,1));
	output.Normal = mul(objectToWorldRotation, input.Normal);
#ifdef DEF_ENABLE_TEXCOORD0
	output.TEX_TEXCOORD0 = input.TEX_TEXCOORD0;
	output.TEX_TEXCOORD0.y = 1.0f - output.TEX_TEXCOORD0.y;
#endif
#ifdef DEF_ENABLE_TEXCOORD1
	output.TEX_TEXCOORD1 = input.TEX_TEXCOORD1;
#endif
#ifdef DEF_ENABLE_TEXCOORD2
	output.TEX_TEXCOORD2 = input.TEX_TEXCOORD2;
#endif
#ifdef DEF_ENABLE_TEXCOORD3
	output.TEX_TEXCOORD3 = input.TEX_TEXCOORD3;
#endif
	return output;
}

PS_OUTPUT ps_main(VS_OUTPUT input)
{
	PS_OUTPUT output = (PS_OUTPUT)0;
		
	output.Colour = float4(1,1,1,1);
	float d = dot(normalize(g_Light_Direction),normalize(input.Normal));
	
	float4 diffuseColour = {1,1,1,1};
	float4 ambientColour = {0,0,0,0};
	
#ifdef DEF_DIFFUSE_FIXED
	diffuseColour = g_DiffuseColour;
#endif
#ifdef DEF_DIFFUSE_TEXTURE
	diffuseColour = 	g_DiffuseTexture.Sample(g_DiffuseTextureSampler, input.DIFFUSE_TEXTURE_TEXCOORD);
#endif
#ifdef DEF_AMBIENT_FIXED
	ambientColour = g_AmbientColour;
#endif
#ifdef DEF_AMBIENT_TEXTURE
	ambientColour = 	g_AmbientTexture.Sample(g_AmbientTextureSampler, input.AMBIENT_TEXTURE_TEXCOORD);
#endif
	
	float4 ambientTerm = ambientColour * g_Light_AmbientColour;
	float4 diffuseTerm = d * diffuseColour * g_Light_DiffuseColour;
	
	output.Colour = float4((ambientTerm + diffuseTerm).rgb,1);
	return output;
}